<script setup lang="ts">
import { ref, onMounted, computed, onUnmounted } from 'vue'
import api from '@/services/api'
import type { NumberOperation } from '@/types'
import LoadingSpinner from './LoadingSpinner.vue'
import { useToastStore } from '@/stores/toast'
import { useNumberInput } from '@/composables/useNumberInput'
import { animateNumber, shake } from '@/utils/animations'

interface CheckNumberResponse {
  check_number: number
}

const props = defineProps<{
  token: string | null
}>()

const { value: number, increment, decrement } = useNumberInput(0)
const error = ref<string>('')
const loading = ref<boolean>(false)
const lastNumber = ref<number | null>(null)

const toastStore = useToastStore()

// 计算数字是否变化
const numberChanged = computed(() => {
  return lastNumber.value !== null && lastNumber.value !== number.value
})

const fetchNumber = async () => {
  try {
    loading.value = true
    const { data } = await api.get<CheckNumberResponse>('/checkNumber')
    lastNumber.value = data.check_number
    number.value = data.check_number
  } catch (e: any) {
    error.value = e.response?.data?.detail || '获取数字失败'
    toastStore.addToast('获取数字失败', 'error')
  } finally {
    loading.value = false
  }
}

const updateNumber = async () => {
  if (!numberChanged.value) {
    const inputEl = document.getElementById('number-input')
    if (inputEl) shake(inputEl)
    toastStore.addToast('数字没有变化哦！', 'warning')
    return
  }

  try {
    loading.value = true
    await api.put<void>(`/updateNumber?number=${number.value}`)
    lastNumber.value = number.value
    
    // 添加动画效果
    if (numberRef.value) {
      animateNumber(numberRef.value, lastNumber.value || 0, number.value)
    }
    
    toastStore.addToast(`数字更新成功！新数字为 ${number.value}`, 'success')
  } catch (e: any) {
    error.value = e.response?.data?.detail || '更新数字失败'
    toastStore.addToast(`更新失败，请重试: ${error.value}`, 'error')
    if (numberRef.value) shake(numberRef.value)
  } finally {
    loading.value = false
  }
}

const postNumber = async () => {
  if (!numberChanged.value) {
    toastStore.addToast('数字没有变化哦！', 'warning')
    return
  }

  try {
    loading.value = true
    await api.post<void>('/postNumber', { number: number.value })
    lastNumber.value = number.value
    toastStore.addToast('数字提交成功！', 'success')
  } catch (e: any) {
    error.value = e.response?.data?.detail || '提交数字失败'
    toastStore.addToast('提交失败，请重试', 'error')
  } finally {
    loading.value = false
  }
}

// 添加键盘快捷键
const handleKeydown = (e: KeyboardEvent) => {
  if (loading.value) return

  if (e.key === 'Enter' && e.ctrlKey) {
    e.preventDefault()
    if (numberChanged.value) {
      postNumber()
    }
  } else if (e.key === 'Enter') {
    e.preventDefault()
    if (numberChanged.value) {
      updateNumber()
    }
  }
}

// 添加按钮点击处理
const handleIncrement = () => {
  if (!loading.value) {
    increment()
  }
}

const handleDecrement = () => {
  if (!loading.value) {
    decrement()
  }
}

// 添加数字动画的引用
const numberRef = ref<HTMLElement | null>(null)

onMounted(() => {
  document.addEventListener('keydown', handleKeydown)
  fetchNumber()
})

onUnmounted(() => {
  document.removeEventListener('keydown', handleKeydown)
})
</script>

<template>
  <div class="nes-container with-title">
    <h3 class="title">数字操作面板</h3>
    
    <template v-if="loading">
      <LoadingSpinner />
    </template>
    
    <template v-else>
      <div v-if="error" class="nes-container is-rounded is-error message">
        <i class="nes-icon close is-small"></i>
        {{ error }}
      </div>

      <div class="number-display nes-container is-dark">
        <i class="nes-icon star is-medium"></i>
        <span 
          ref="numberRef"
          class="number" 
          :class="{ 'number-changed': numberChanged }"
        >
          {{ number }}
        </span>
      </div>

      <div class="operations">
        <div class="input-group">
          <label for="number-input">输入数字：</label>
          <div class="input-wrapper">
            <button 
              class="nes-btn is-small"
              @click="handleDecrement"
              :disabled="loading"
              tabindex="0"
            >-</button>
            <input 
              id="number-input"
              v-model.number="number" 
              type="number" 
              class="nes-input"
              :class="{ 'is-changed': numberChanged }"
              :disabled="loading"
              min="0"
              max="9999"
              tabindex="0"
            />
            <button 
              class="nes-btn is-small"
              @click="handleIncrement"
              :disabled="loading"
              tabindex="0"
            >+</button>
            <i v-if="numberChanged" class="nes-icon coin is-small bounce"></i>
          </div>
        </div>

        <div class="button-group">
          <button 
            @click="updateNumber" 
            :disabled="loading || !numberChanged"
            class="nes-btn is-primary"
          >
            <i class="nes-icon coin is-small"></i>
            更新数字
          </button>
          <button 
            @click="postNumber" 
            :disabled="loading || !numberChanged"
            class="nes-btn is-success"
          >
            <i class="nes-icon trophy is-small"></i>
            提交数字
          </button>
        </div>
      </div>

      <div class="keyboard-tips nes-container is-dark">
        <p>快捷键提示：</p>
        <ul>
          <li>Enter: 更新数字</li>
          <li>Ctrl + Enter: 提交数字</li>
        </ul>
      </div>
    </template>
  </div>
</template>

<style scoped>
.message {
  margin-bottom: 1rem;
  padding: 1rem;
  text-align: center;
  font-size: 0.8rem;
  display: flex;
  align-items: center;
  gap: 1rem;
  animation: shake 0.5s ease-in-out;
}

.message i {
  flex-shrink: 0;
}

.number-display {
  margin: 2rem 0;
  padding: 2rem;
  text-align: center;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1rem;
}

.number {
  font-size: 2.5rem;
  color: #fff;
  text-shadow: 2px 2px 0 var(--dark-color);
  transition: all 0.3s ease;
  padding: 0.5rem 1rem;
  background-color: rgba(0, 0, 0, 0.2);
  border-radius: 4px;
}

.operations {
  display: flex;
  flex-direction: column;
  gap: 2rem;
}

.input-group {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.input-group label {
  font-size: 0.8rem;
  padding-left: 0.5rem;
}

.button-group {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.nes-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
}

.nes-btn i {
  margin: 0;
}

@media (min-width: 768px) {
  .button-group {
    flex-direction: row;
    justify-content: center;
  }
}

.nes-btn:disabled {
  opacity: 0.7;
  cursor: not-allowed;
  transform: none !important;
}

.nes-input:disabled {
  opacity: 0.7;
  cursor: not-allowed;
  background-color: #f5f5f5;
}

@keyframes shake {
  0%, 100% { transform: translateX(0); }
  20%, 60% { transform: translateX(-5px); }
  40%, 80% { transform: translateX(5px); }
}

.shake {
  animation: shake 0.5s cubic-bezier(0.36, 0.07, 0.19, 0.97) both;
}

.input-wrapper {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.input-wrapper .nes-btn.is-small {
  padding: 0.25rem 0.5rem;
  min-width: auto;
  font-size: 1rem;
  line-height: 1;
}

.input-wrapper input {
  text-align: center;
  font-size: 1.2rem;
  letter-spacing: 2px;
  transition: all 0.3s ease;
}

.input-wrapper input:focus {
  transform: scale(1.02);
  box-shadow: 0 0 0 4px rgba(32, 156, 238, 0.2);
}

.number-changed {
  color: var(--warning-color);
  animation: pulse 1s infinite;
  background-color: rgba(255, 255, 255, 0.1);
}

.is-changed {
  border-color: var(--warning-color);
}

@keyframes pulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.05); }
}

@keyframes bounce {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-5px); }
}

.keyboard-tips {
  margin-top: 2rem;
  font-size: 0.7rem;
  padding: 1rem;
}

.keyboard-tips ul {
  list-style: none;
  margin: 0.5rem 0 0;
  padding: 0;
}

.keyboard-tips li {
  margin: 0.25rem 0;
  color: var(--warning-color);
}

/* 优化按钮悬停效果 */
.nes-btn:not(:disabled):hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 0 var(--border-color);
}

.nes-btn:not(:disabled):active {
  transform: translateY(0);
  box-shadow: 0 2px 0 var(--border-color);
}
</style> 